package edu.mtsu.csci3033;

import java.awt.*;
import java.util.Random;



/** Description of TeamProject Table class
 *
 * @author Dan Woodson
 * @author Trevor Powis
 * @author Kristi Brockelsby
 * @author Jared Gailey
 * @version 1: October 26, 2009
 */
public class Table
{
	private char[][]values = new char[10][10];	//probably better to use array of integer values(0 or 1)
	Image imgO;		// stores O image
	Image imgX;		// stores X image
	Image itemImg; // stores the item image
	private int Rows;	// stores number of rows
	private int Columns;	// stores number of columns
	private int BoxWidth ;	// stores the width of a box
	private int BoxHeight;	// stores the height of a box
	public Point Pos = new Point();	// creates a new point to draw from

	private int tableHeight;	// stores the height of the table
	private int tableWidth;		// stores the width of the table

	private int changedRow;		// stores the row that was changed
	private int changedCol;		// stores the column that was changed


 	 /** Description of public Table( x, y, width, height, col, rows, X, O)
  	*
  	* Constructor function
	* @param x	contains an x-coordinate of the table
	* @param y	contains a y-coordinate of the table
	* @param width	contains the width of a box in the table
	* @param height	contains the height of a box in the table
	* @param col	contains the number of columns in the table
	* @param rows	contains the number of rows in the table
	* @param X	contains the X image to be put into the table
	* @param O	contains the O image to be put into the table
	* @param itemImg contains the "target" image ie: ant, fly, unicorn
	* @return	none
  	*/
	public Table(int x, int y, int width, int height, int col, int rows, Image X, Image O, Image itemImg)
	{
		Rows = rows;
		Columns = col;
		BoxWidth = width;
		BoxHeight = height;
		Pos.x = x;
		Pos.y = y;
		imgX = X;
		imgO = O;
		this.itemImg = itemImg;
		tableHeight = Rows*BoxHeight;
		tableWidth = Columns*BoxWidth;
		this.setValues();
	}


 	/** Description of draw(Graphics g)
  	*
	* Function draws the lines used in the table
	* @param g	object used to draw the table
	* @return	none
  	*/
	public void draw(Graphics g)
	{
		//draw vertical table lines
		for (int i = 0 ; i <= Columns ; i++)
			g.drawLine(i*BoxWidth + Pos.x, Pos.y, i*BoxWidth + Pos.x, tableHeight+Pos.y);

		//draw horizontal table line
		for(int i = 0 ; i <= Rows ; i++)
			g.drawLine(Pos.x, i*BoxHeight + Pos.y, tableWidth+Pos.x, i*BoxHeight + Pos.y);

		//draw values
		drawValues(g);
	}



	/** Description of swapSquareValue( x, y )
  	*
	* Function swaps an X and O value in the table
	* @param x
	* @param y
	* @return	none
  	*/
	public void swapSquareValue(int x, int y)
	{
		if (this.isDrawable(x, y))
		{
			int col = this.getColumn(x)-1;
			int row = this.getRow(y)-1;

			if(values[row][col] == 'X')
				values[row][col] = 'O';
			else if(values[row][col] == 'O')
				values[row][col] = 'X';
			else
				System.out.println("ERROR SWAPPING SQUARE VALUE");
		}
		else
		  System.out.println("says not drawable");
	}

	/** Description of getValue( col, row )
  	*
	* Function draws the lines used in the table
	* @param col	contains a column coordinate
	* @param row	contains a row coordinate
	* @return	returns table coordinates
  	*/
	public char getValue(int col, int row)
	{
		return values[row][col];
	}


	/** Description of isDrawable( x, y )
  	*
	* Function returns true if (x,y) is a point in the table
	* @param x	contains a table column
	* @param y	contains a table row
	* @return	boolean if (x,y) is a point in the table
  	*/
	public boolean isDrawable(int x, int y)
	{
		if((this.getRow(y)!=-1)||(this.getColumn(x)!=-1))
			return true;
		else
			return false;
	}


	/** Description of addRow()
  	*
	* Function adds a row to the table
	* @return	none
  	*/
	public void addRow()
	{
		Rows++;		// increment number of rows
		tableHeight = (Rows*BoxHeight);  // store table height
		int numOfXs = 0;	// stores the number of X values in table

		for (int c=0; c < Columns; c++) {
      			numOfXs = 0;

			for(int r = 0; r < Rows - 1; r++){
				if(values[r][c] == 'X'){
          			numOfXs++;	// increment number of X values

         			System.out.println("in column " + c + "new x found at " +
					 r + " " + c + ", numOfXs = " + numOfXs);
        }

        	if(numOfXs % 2 == 0){
        		values[Rows - 1][c] = 'O';
        	}

        	else{
        		values[Rows - 1][c] = 'X';
       		}

      			}//end inner for
		System.out.println("end of column " + c);
    		}//end outer for

 	}// end function


	/** Description of addColumn()
  	*
	* Function adds a column to the table
	* @return	none
  	*/
	public void addColumn()
	{
		Columns++;  // increment columns
		tableWidth = (Columns*BoxWidth);  // stores the table width
		int numOfXs = 0;  // stores the number of X values

	  for (int r=0; r < Rows; r++) {
		  numOfXs = 0;
			for(int c = 0; c < Columns - 1; c++){
			  if(values[r][c] == 'X'){
          numOfXs++;  // increment number of X values

          System.out.println("in row " + r + "new x found at " + r + " " + c + ", numOfXs = " + numOfXs);
        }
        if(numOfXs % 2 == 0){
          values[r][Columns - 1] = 'O';
        }
        else{
          values[r][Columns - 1] = 'X';
        }
      }//end inner for
			System.out.println("end of row " + r);
    }
	}


  private void drawValues(Graphics g)
	{
		Point drawPoint = new Point();  // creates a new point to draw from

		//loop through all points, assigning them an 'X' (itemImg) or 'O' (nothing)
		for (int r=0; r < Rows-1; r++)
		  for (int c=0; c < Columns-1; c++) {
		    //the width/height / 2 places the points on grid line intersections, not the boxes they create
			  drawPoint.x = Pos.x + (BoxWidth) * c + (BoxWidth/2);  // x-draw point
				drawPoint.y = Pos.y + (BoxHeight) * r + (BoxHeight/2);  // y-draw point

        //if value == 'X' draw itemImg
		    if (values[r][c] == 'X') {
          g.drawImage(itemImg,drawPoint.x+1, drawPoint.y+1, BoxWidth-1, BoxHeight-1, null);
        }
        //else, do nothing
		    else {

		    }
        //debug
		    //System.out.print((char)values[r][c]);
      }

		  g.setColor(Color.black);  // set color of table to black
	}

	//fills array with random values
	private void setValues()
	{

		for (int r=0; r < Rows; r++)
      			for (int c=0; c < Columns; c++) {
        			values[r][c] = this.randomChar();
     			}
	}


	//randomly return 'X' or 'O'
	private char randomChar()
  	{
    	char randomValue;
		Random RandomGen = new Random();

		if (RandomGen.nextInt(2)==0)
			randomValue = 'O';

		else
			randomValue ='X';

		return randomValue;
  	}


	private int getColumn(int x)
	{
		int offsetx=0;
		for (int i = 0 ; i < Columns ; i++) {
			offsetx = i*BoxWidth;
			if((x>Pos.x+offsetx)&& (x<Pos.x+offsetx+BoxWidth))
				return i+1;
		}
		return -1;
	}

	private int getRow(int y)
	{
		int offsety=0;
		for (int i = 0 ; i < Rows ; i++)
		{
			offsety = i*BoxHeight;
			if((y>Pos.y+offsety)&& (y<Pos.x+offsety+BoxHeight))
				return i+1;
		}

		return -1;
	}



	/** Description of randomChangeFunc()
	 *
	 * Function randomly determines which table value to change
	 * @param 	none
	 * @return	void
	 */
	public void randomChangeFunc()
	{

	  	//get random row and column
	  	Random rand=new Random();

    		int randRow = rand.nextInt(Rows);    // gets and holds a random column
    		int randCol = rand.nextInt(Columns); // gets and holds a random column

    		System.out.println("randRow = " + randRow + " randCol = " + randCol);

		if(values[randRow][randCol] == 'X')
			values[randRow][randCol] = 'O';
		else if(values[randRow][randCol] == 'O')
			values[randRow][randCol] = 'X';
		else
			System.out.println("ERROR SWAPPING SQUARE VALUE");  // error message

    		//set globals
    		changedRow = randRow;
   		changedCol = randCol;

 	 }


	/** Description of checkGuess(guessCol, guessRow)
	*
	* Function determines if the player guess was correct or incorrect
	* @param guessCol	contains the column coordinate of the player guess
	* @param guessRow	contains the row coordinate of the player guess
	* @return		bool containing if the guess was right or not
	*/
 	public boolean checkGuess(int guessCol, int guessRow)
	{

	    int gCol = this.getColumn(guessCol)-1;   // contains the user guessed column
	    int gRow = this.getRow(guessRow)-1;	     // contains the user guessed row

	    System.out.println("gCol = " + gCol + " gRow = " + gRow);

	    if(gCol == changedCol && gRow == changedRow){
      		System.out.println("CORRECT!!!");   // prints if guess was right (debug)
     		return true;

	    }  // end if

	    else{
      		System.out.println("incorrect :(");  // prints if guess was wrong (debug)
      		return false;
    	    }

        }

}
